#ifndef __data__h__
#define __data__h__

#include<QString>
#include<QIcon>
#include<QByteArray>
#include<QUuid>
#include<QDateTime>
#include<QPixmap>
#include<QDebug>
#include<QFile>
namespace Mode
{
/**********************************************
     *   工具函数集合
     * ********************************************
     */
//构建格式化时间字符串
static inline QString makeFormatTime(int64_t timestamp)
{
    QDateTime time = QDateTime::fromSecsSinceEpoch(timestamp);
    return time.toString("MM-dd HH:mm:ss");
}
/*获取当前时间戳*/
static inline int64_t CurrentTime()
{
    return QDateTime::currentSecsSinceEpoch();
}
/*日志模块*/
enum LOGLEVEL
{
    INFO,
    DEBUG,
    WARN,
    ERROR,
    FATAL
};
//noquote表示取消自动带上的""符号
#define LOG(level) qDebug().noquote()<<forMatLog(level,__FILE__,__LINE__)

//日志格式化字符串
static inline QString forMatLog(int level,const char* filename,int line)
{
    QString levelStr;
    switch(level)
    {
    case LOGLEVEL::INFO:
        levelStr = "INFO";
        break;
    case LOGLEVEL::DEBUG:
        levelStr = "DEBUG";
        break;
    case LOGLEVEL::WARN:
        levelStr = "WARN";
        break;
    case LOGLEVEL::ERROR:
        levelStr ="ERROR";
        break;
    case LOGLEVEL::FATAL:
        levelStr ="FATAL";
        break;
    default:
        levelStr ="unknow";
        break;
    }
    return "[" + levelStr
           + "]"
           +  "["
           + QString(filename)
           + "]"
           + "["
           + QString::number(line)
           +"]"
           +"["
           +makeFormatTime(CurrentTime())
           +"]" + ":";
}

//将QByteArray转换成QIcon类型
/* 二者并不能直接转换，但是可以借助QPixmap类型进行间接转换
     */
static inline QIcon makeQIconFromQByteArray(const QByteArray& byteArray)
{
    QPixmap pixMap;
    pixMap.loadFromData(byteArray);
    QIcon icon(pixMap);
    return icon;
}
/*读取指定路径下的文件，并且存放到QByteArray中*/
static inline QByteArray loadFileToQbyteArray(const QString& path)
{
    QFile in(path);
    bool ok = in.open(QFile::ReadOnly);
    if(!ok)
    {
        qDebug()<<"打开文件"<<path<<"失败";
        return  QByteArray();
    }
    QByteArray content = in.readAll();
    return content;
}
//往指定文件中写入一个QByteArray
static inline bool LoadQbyteArrayToFile(const QString& path,const QByteArray& data)
{
    QFile out(path);
    bool ok = out.open(QFile::WriteOnly);
    if(!ok)
    {
        qDebug()<<"打开文件"<<path<<"失败!";
        return false;
    }
    qint64 n = out.write(data);//只是写入到QT内置的缓冲区而已
    //注意刷新缓冲区！
    out.flush();
    if(n < 0)
    {
        qDebug()<<"向文件"<<path<<"写入数据失败!";
        return false;
    }
    return true;
}
/**********************************************
     *   用户信息类
     * ********************************************
     */
class UserInfo
{
public:
    QString uid = "";        //用户id
    QString name = "";       //用户昵称
    QString desc = "";       //用户签名
    QString phone = "";      //用户绑定的手机号
    QIcon   avater;          //头像
};
/**********************************************
     *  消息类型
     * ********************************************
     */
enum MessageType
{
    TEXT_TYPE,
    IMAGE_TYPE,
    FILE_TYPE,
    SPEECH_TYPE
};
/**********************************************
     *  聊天信息类
     * ********************************************
     */
class Message
{
public:
    QString messageId = "";          //消息的标识符id
    QString chatSessionId = "";      //表示消息所属于哪个会话
    QString time = "";               //消息的发送时间
    UserInfo sender;                 //谁发送的消息
    MessageType messageType;         //消息正文的类型
    QByteArray content;         //消息内容
    QString fileId = "";             //只有当正文内容不是文本内容时才会生效
    QString fileName = "";           //只有当正文内容为文件时才会填充该字段，因为要显示文件名给用户
    //工厂模式构建消息对象
    static Message makeMessage(const MessageType& messageType,
                               const QString& chatSessionId,
                               const UserInfo& sender,
                               const QByteArray& content,
                               QString& extraInfo)
    {
        switch(messageType)
        {
        case TEXT_TYPE:
            return makeTextMessage(chatSessionId,sender,content);
            break;
        case IMAGE_TYPE:
            return makeImageMessage(chatSessionId,sender,content);
            break;
        case FILE_TYPE:
            return makeFileMessage(chatSessionId,sender,content,extraInfo);
            break;
        case SPEECH_TYPE:
            return makeSpeechMessage(chatSessionId,sender,content);
            break;
        default:
            return Message();
        }
    }
public:
    //构建唯一的消息messageId
    static QString makeMessageId()
    {
        //使用uuid算法
        return "M" + QUuid::createUuid().toString().sliced(25,12);
    }
    /*工厂子方法*/
    //构建文本消息
    static Message makeTextMessage(const QString& chatSessionId,
                                   const UserInfo& sender,
                                   const QByteArray& content)
    {
        Message textMessageObj;
        textMessageObj.messageType = MessageType::TEXT_TYPE;
        textMessageObj.chatSessionId = chatSessionId;
        textMessageObj.sender = sender;
        textMessageObj.content = content;
        textMessageObj.messageId = makeMessageId();
        textMessageObj.time = makeFormatTime(CurrentTime());
        textMessageObj.fileId = "";//No used
        textMessageObj.fileName = "";//No used
        return textMessageObj;
    }
    /*构建图片消息*/
    static Message makeImageMessage(const QString& chatSessionId,
                                    const UserInfo& sender,
                                    const QByteArray& content)
    {
        Message imageMessageObj;
        imageMessageObj.messageType = MessageType::IMAGE_TYPE;
        imageMessageObj.chatSessionId = chatSessionId;
        imageMessageObj.sender = sender;
        imageMessageObj.content = content;
        imageMessageObj.messageId = makeMessageId();
        imageMessageObj.time = makeFormatTime(CurrentTime());
        imageMessageObj.fileId = "";//No used
        imageMessageObj.fileName = "";//No used
        return imageMessageObj;
    }
    /*构建文件消息*/
    static Message makeFileMessage(const QString& chatSessionId,
                                   const UserInfo& sender,
                                   const QByteArray& content,
                                   QString& extraInfo)
    {
        Message fileMessageObj;
        fileMessageObj.messageType = MessageType::FILE_TYPE;
        fileMessageObj.chatSessionId = chatSessionId;
        fileMessageObj.sender = sender;
        fileMessageObj.content = content;
        fileMessageObj.messageId = makeMessageId();
        fileMessageObj.time = makeFormatTime(CurrentTime());
        fileMessageObj.fileId = "";//外部填充
        fileMessageObj.fileName = extraInfo;
        return fileMessageObj;
    }
    static Message makeSpeechMessage(const QString& chatSessionId,
                                     const UserInfo& sender,
                                     const QByteArray& content)
    {
        Message speechMessageObj;
        speechMessageObj.messageType = MessageType::SPEECH_TYPE;
        speechMessageObj.chatSessionId = chatSessionId;
        speechMessageObj.sender = sender;
        speechMessageObj.content = content;
        speechMessageObj.messageId = makeMessageId();
        speechMessageObj.time = makeFormatTime(CurrentTime());
        speechMessageObj.fileId = "";//no used
        speechMessageObj.fileName = "";//no used
        return speechMessageObj;
    }
};
/**********************************************
     *   会话信息类
     * ********************************************
     */
class ChatSessionInfo
{
public:
    QString chatSessionId = "";      //会话id
    QString chatSessionName = "";    //会话名称
    QIcon avater;               //会话头像
    Message lastMessage;        //最新的聊天记录
};
}//namespace Mode end

#endif /*data.h*/
